package net.starwifi.duobao.service.impl;

import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.starwifi.duobao.entity.Article;
import net.starwifi.duobao.mvc.Filter;
import net.starwifi.duobao.mvc.Order;
import net.starwifi.duobao.service.ArticleService;
import net.starwifi.duobao.service.BaseServiceImpl;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by Administrator on 2015/8/7.
 */
@Service
public class ArticleServiceImpl extends BaseServiceImpl<Article,Long> implements ArticleService {

    /** 查看点击数时间 */
    private long viewHitsTime = System.currentTimeMillis();

    @Resource(name = "ehCacheManager")
    private CacheManager cacheManager;



    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "article")
    public List<Article> getMListData(int firstIndex, int maxResult, List<Filter> filters, List<Order> orderBy) {
        return super.getMListData(firstIndex, maxResult, filters, orderBy);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "article")
    public Article find(Long entityId) {
        return super.find(entityId);
    }

    @Override
    @Transactional
    @CacheEvict(value = "article", allEntries = true)
    public void save(Article entity) {
        super.save(entity);
    }

    @Override
    @Transactional
    @CacheEvict(value = "article", allEntries = true)
    public Article update(Article entity) {
        return super.update(entity);
    }

    @Override
    @Transactional
    @CacheEvict(value = "article", allEntries = true)
    public Article update(Article entity, String... ignoreProperties) {
        return super.update(entity, ignoreProperties);
    }




    public long viewHits(Long id) {
        Ehcache cache = cacheManager.getEhcache(Article.HITS_CACHE_NAME);
        Element element = cache.get(id);
        Long hits;
        if (element != null) {
            hits = (Long) element.getObjectValue();
        } else {
            Article article = find(id);
            if (article == null) {
                return 0L;
            }
            hits = article.getHits();
        }
        hits++;
        cache.put(new Element(id, hits));
        long time = System.currentTimeMillis();
        if (time > viewHitsTime + Article.HITS_CACHE_INTERVAL) {
            viewHitsTime = time;
            updateHits();
            cache.removeAll();
        }
        return hits;
    }

    public void destroy() throws Exception {
        updateHits();
    }

    /**
     * 更新点击数
     */
    @SuppressWarnings("unchecked")
    private void updateHits() {
        Ehcache cache = cacheManager.getEhcache(Article.HITS_CACHE_NAME);
        List<Long> ids = cache.getKeys();
        for (Long id : ids) {
            Article article = find(id);
            if (article != null) {
                Element element = cache.get(id);
                long hits = (Long) element.getObjectValue();
                article.setHits(hits);
                update(article);
            }
        }
    }

}
